using Senparc.Weixin.Context;
using Senparc.Weixin.Exceptions;
using Senparc.Weixin.MessageHandlers;
using Senparc.Weixin.MP.AppStore;
using Senparc.Weixin.MP.Entities;
using Senparc.Weixin.MP.Entities.Request;
using Senparc.Weixin.MP.Helpers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Linq;
using Tencent;
namespace Senparc.Weixin.MP.MessageHandlers
{
	public abstract class MessageHandler<TC> : MessageHandler<TC, IRequestMessageBase, IResponseMessageBase>, IMessageHandler, IMessageHandler<IRequestMessageBase, IResponseMessageBase>, IMessageHandlerDocument where TC : class, IMessageContext<IRequestMessageBase, IResponseMessageBase>, new()
	{
		public static WeixinContext<TC, IRequestMessageBase, IResponseMessageBase> GlobalWeixinContext = new WeixinContext<TC, IRequestMessageBase, IResponseMessageBase>();
		private PostModel _postModel;
		public override WeixinContext<TC, IRequestMessageBase, IResponseMessageBase> WeixinContext
		{
			get
			{
				return MessageHandler<TC>.GlobalWeixinContext;
			}
		}
		public XDocument EcryptRequestDocument
		{
			get;
			set;
		}
		public override XDocument ResponseDocument
		{
			get
			{
				XDocument result;
				if (this.ResponseMessage == null)
				{
					result = null;
				}
				else
				{
					result = (this.ResponseMessage as ResponseMessageBase).ConvertEntityToXml<ResponseMessageBase>();
				}
				return result;
			}
		}
		public override XDocument FinalResponseDocument
		{
			get
			{
				XDocument result;
				if (this.ResponseDocument == null)
				{
					result = null;
				}
				else
				{
					if (!this.UsingEcryptMessage)
					{
						result = this.ResponseDocument;
					}
					else
					{
						string sTimeStamp = DateTime.Now.Ticks.ToString();
						string sNonce = DateTime.Now.Ticks.ToString();
						WXBizMsgCrypt wXBizMsgCrypt = new WXBizMsgCrypt(this._postModel.Token, this._postModel.EncodingAESKey, this._postModel.AppId);
						string text = null;
						wXBizMsgCrypt.EncryptMsg(this.ResponseDocument.ToString().Replace("\r\n", "\n"), sTimeStamp, sNonce, ref text);
						result = XDocument.Parse(text);
					}
				}
				return result;
			}
		}
		public new IRequestMessageBase RequestMessage
		{
			get
			{
				return base.RequestMessage;
			}
			set
			{
				base.RequestMessage = value;
			}
		}
		public new IResponseMessageBase ResponseMessage
		{
			get
			{
				return base.ResponseMessage;
			}
			set
			{
				base.ResponseMessage = value;
			}
		}
		public bool UsingEcryptMessage
		{
			get;
			set;
		}
		public bool UsingCompatibilityModelEcryptMessage
		{
			get;
			set;
		}
		public DeveloperInfo DeveloperInfo
		{
			get;
			set;
		}
		public MessageHandler(Stream inputStream, PostModel postModel = null, int maxRecordCount = 0, DeveloperInfo developerInfo = null) : base(inputStream, maxRecordCount, postModel)
		{
			this.DeveloperInfo = developerInfo;
		}
		public MessageHandler(XDocument requestDocument, PostModel postModel = null, int maxRecordCount = 0, DeveloperInfo developerInfo = null) : base(requestDocument, maxRecordCount, postModel)
		{
			this.DeveloperInfo = developerInfo;
		}
		public MessageHandler(RequestMessageBase requestMessageBase, PostModel postModel = null, int maxRecordCount = 0, DeveloperInfo developerInfo = null) : base(requestMessageBase, maxRecordCount, postModel)
		{
			this.DeveloperInfo = developerInfo;
			XDocument postDataDocument = requestMessageBase.ConvertEntityToXml<RequestMessageBase>();
			base.CommonInitialize(postDataDocument, maxRecordCount, postModel);
		}
		public override XDocument Init(XDocument postDataDocument, object postData = null)
		{
			this._postModel = (postData as PostModel);
			string sPostData = postDataDocument.ToString();
			XDocument xDocument = postDataDocument;
			XDocument result;
			if (this._postModel != null && postDataDocument.Root.Element("Encrypt") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("Encrypt").Value))
			{
				this.UsingEcryptMessage = true;
				this.EcryptRequestDocument = postDataDocument;
				WXBizMsgCrypt wXBizMsgCrypt = new WXBizMsgCrypt(this._postModel.Token, this._postModel.EncodingAESKey, this._postModel.AppId);
				string text = null;
				int num = wXBizMsgCrypt.DecryptMsg(this._postModel.Msg_Signature, this._postModel.Timestamp, this._postModel.Nonce, sPostData, ref text);
				if (num != 0)
				{
					base.CancelExcute = true;
					result = null;
					return result;
				}
				if (postDataDocument.Root.Element("FromUserName") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("FromUserName").Value))
				{
					this.UsingCompatibilityModelEcryptMessage = true;
				}
				xDocument = XDocument.Parse(text);
			}
			this.RequestMessage = RequestMessageFactory.GetRequestEntity(xDocument, null);
			if (this.UsingEcryptMessage)
			{
				this.RequestMessage.Encrypt = postDataDocument.Root.Element("Encrypt").Value;
			}
			if (WeixinContextGlobal.UseWeixinContext)
			{
				this.WeixinContext.InsertMessage(this.RequestMessage);
			}
			result = xDocument;
			return result;
		}
		public TR CreateResponseMessage<TR>() where TR : ResponseMessageBase
		{
			TR result;
			if (this.RequestMessage == null)
			{
				result = default(TR);
			}
			else
			{
				result = this.RequestMessage.CreateResponseMessage<TR>();
			}
			return result;
		}
		public override void Execute()
		{
			if (!base.CancelExcute)
			{
				this.OnExecuting();
				if (!base.CancelExcute)
				{
					try
					{
						if (this.RequestMessage != null)
						{
							switch (this.RequestMessage.MsgType)
							{
							case RequestMsgType.Text:
							{
								RequestMessageText requestMessage = this.RequestMessage as RequestMessageText;
								this.ResponseMessage = (this.OnTextOrEventRequest(requestMessage) ?? this.OnTextRequest(requestMessage));
								break;
							}
							case RequestMsgType.Location:
								this.ResponseMessage = this.OnLocationRequest(this.RequestMessage as RequestMessageLocation);
								break;
							case RequestMsgType.Image:
								this.ResponseMessage = this.OnImageRequest(this.RequestMessage as RequestMessageImage);
								break;
							case RequestMsgType.Voice:
								this.ResponseMessage = this.OnVoiceRequest(this.RequestMessage as RequestMessageVoice);
								break;
							case RequestMsgType.Video:
								this.ResponseMessage = this.OnVideoRequest(this.RequestMessage as RequestMessageVideo);
								break;
							case RequestMsgType.Link:
								this.ResponseMessage = this.OnLinkRequest(this.RequestMessage as RequestMessageLink);
								break;
							case RequestMsgType.ShortVideo:
								this.ResponseMessage = this.OnShortVideoRequest(this.RequestMessage as RequestMessageShortVideo);
								break;
							case RequestMsgType.Event:
							{
								RequestMessageText requestMessage2 = (this.RequestMessage as IRequestMessageEventBase).ConvertToRequestMessageText();
								this.ResponseMessage = (this.OnTextOrEventRequest(requestMessage2) ?? this.OnEventRequest(this.RequestMessage as IRequestMessageEventBase));
								break;
							}
							default:
								throw new UnknownRequestMsgTypeException("未知的MsgType请求类型", null);
							}
							if (WeixinContextGlobal.UseWeixinContext && this.ResponseMessage != null)
							{
								this.WeixinContext.InsertMessage(this.ResponseMessage);
							}
						}
					}
					catch (Exception ex)
					{
						throw new MessageHandlerException("MessageHandler中Execute()过程发生错误：" + ex.Message, ex);
					}
					finally
					{
						this.OnExecuted();
					}
				}
			}
		}
		public new virtual void OnExecuting()
		{
			bool arg_2C_0;
			if (base.OmitRepeatedMessage)
			{
				TC currentMessageContext = this.CurrentMessageContext;
				arg_2C_0 = (currentMessageContext.RequestMessages.Count <= 1);
			}
			else
			{
				arg_2C_0 = true;
			}
			if (!arg_2C_0)
			{
				TC currentMessageContext = this.CurrentMessageContext;
				List<IRequestMessageBase> arg_63_0 = currentMessageContext.RequestMessages;
				currentMessageContext = this.CurrentMessageContext;
				IRequestMessageBase requestMessageBase = arg_63_0[currentMessageContext.RequestMessages.Count - 2];
				if ((requestMessageBase.MsgId != 0L && requestMessageBase.MsgId == this.RequestMessage.MsgId) || (requestMessageBase.CreateTime == this.RequestMessage.CreateTime && requestMessageBase.MsgType == this.RequestMessage.MsgType))
				{
					base.CancelExcute = true;
					return;
				}
			}
			base.OnExecuting();
			bool arg_F9_0;
			if (this.DeveloperInfo == null)
			{
				TC currentMessageContext = this.CurrentMessageContext;
				arg_F9_0 = (currentMessageContext.AppStoreState != AppStoreState.Enter);
			}
			else
			{
				arg_F9_0 = false;
			}
			if (!arg_F9_0)
			{
			}
		}
		public new virtual void OnExecuted()
		{
			base.OnExecuted();
		}
		public abstract IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage);
		public virtual IResponseMessageBase OnTextOrEventRequest(RequestMessageText requestMessage)
		{
			return null;
		}
		public virtual IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnLocationRequest(RequestMessageLocation requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnImageRequest(RequestMessageImage requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnVoiceRequest(RequestMessageVoice requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnVideoRequest(RequestMessageVideo requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnLinkRequest(RequestMessageLink requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnShortVideoRequest(RequestMessageShortVideo requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEventRequest(IRequestMessageEventBase requestMessage)
		{
			IRequestMessageEventBase requestMessageEventBase = this.RequestMessage as IRequestMessageEventBase;
			IResponseMessageBase result;
			switch (requestMessageEventBase.Event)
			{
			case Event.ENTER:
				result = this.OnEvent_EnterRequest(this.RequestMessage as RequestMessageEvent_Enter);
				break;
			case Event.LOCATION:
				result = this.OnEvent_LocationRequest(this.RequestMessage as RequestMessageEvent_Location);
				break;
			case Event.subscribe:
				result = this.OnEvent_SubscribeRequest(this.RequestMessage as RequestMessageEvent_Subscribe);
				break;
			case Event.unsubscribe:
				result = this.OnEvent_UnsubscribeRequest(this.RequestMessage as RequestMessageEvent_Unsubscribe);
				break;
			case Event.CLICK:
				result = this.OnEvent_ClickRequest(this.RequestMessage as RequestMessageEvent_Click);
				break;
			case Event.scan:
				result = this.OnEvent_ScanRequest(this.RequestMessage as RequestMessageEvent_Scan);
				break;
			case Event.VIEW:
				result = this.OnEvent_ViewRequest(this.RequestMessage as RequestMessageEvent_View);
				break;
			case Event.MASSSENDJOBFINISH:
				result = this.OnEvent_MassSendJobFinishRequest(this.RequestMessage as RequestMessageEvent_MassSendJobFinish);
				break;
			case Event.TEMPLATESENDJOBFINISH:
				result = this.OnEvent_TemplateSendJobFinishRequest(this.RequestMessage as RequestMessageEvent_TemplateSendJobFinish);
				break;
			case Event.scancode_push:
				result = this.OnEvent_ScancodePushRequest(this.RequestMessage as RequestMessageEvent_Scancode_Push);
				break;
			case Event.scancode_waitmsg:
				result = this.OnEvent_ScancodeWaitmsgRequest(this.RequestMessage as RequestMessageEvent_Scancode_Waitmsg);
				break;
			case Event.pic_sysphoto:
				result = this.OnEvent_PicSysphotoRequest(this.RequestMessage as RequestMessageEvent_Pic_Sysphoto);
				break;
			case Event.pic_photo_or_album:
				result = this.OnEvent_PicPhotoOrAlbumRequest(this.RequestMessage as RequestMessageEvent_Pic_Photo_Or_Album);
				break;
			case Event.pic_weixin:
				result = this.OnEvent_PicWeixinRequest(this.RequestMessage as RequestMessageEvent_Pic_Weixin);
				break;
			case Event.location_select:
				result = this.OnEvent_LocationSelectRequest(this.RequestMessage as RequestMessageEvent_Location_Select);
				break;
			case Event.card_pass_check:
				result = this.OnEvent_Card_Pass_CheckRequest(this.RequestMessage as RequestMessageEvent_Card_Pass_Check);
				break;
			case Event.card_not_pass_check:
				result = this.OnEvent_Card_Not_Pass_CheckRequest(this.RequestMessage as RequestMessageEvent_Card_Not_Pass_Check);
				break;
			case Event.user_card:
				result = this.OnEvent_User_CardRequest(this.RequestMessage as RequestMessageEvent_User_Card);
				break;
			case Event.user_del_card:
				result = this.OnEvent_User_Del_CardRequest(this.RequestMessage as RequestMessageEvent_User_Del_Card);
				break;
			case Event.kf_create_session:
				result = this.OnEvent_Kf_Create_SessionRequest(this.RequestMessage as RequestMessageEvent_Kf_Create_Session);
				break;
			case Event.kf_close_session:
				result = this.OnEvent_Kf_Close_SessionRequest(this.RequestMessage as RequestMessageEvent_Kf_Close_Session);
				break;
			case Event.kf_switch_session:
				result = this.OnEvent_Kf_Switch_SessionRequest(this.RequestMessage as RequestMessageEvent_Kf_Switch_Session);
				break;
			case Event.poi_check_notify:
				result = this.OnEvent_Poi_Check_NotifyRequest(this.RequestMessage as RequestMessageEvent_Poi_Check_Notify);
				break;
			case Event.WifiConnected:
				result = this.OnEvent_WifiConnected(this.RequestMessage as RequestMessageEvent_WifiConnected);
				break;
			case Event.user_consume_card:
				result = this.OnEvent_User_Consume_Card(this.RequestMessage as RequestMessageEvent_User_Consume_Card);
				break;
			case Event.user_view_card:
				result = this.OnEvent_User_View_Card(this.RequestMessage as RequestMessageEvent_User_View_Card);
				break;
			case Event.user_enter_session_from_card:
				result = this.OnEvent_User_Enter_Session_From_Card(this.RequestMessage as RequestMessageEvent_User_Enter_Session_From_Card);
				break;
			case Event.merchant_order:
				result = this.OnEvent_Merchant_Order(this.RequestMessage as RequestMessageEvent_Merchant_Order);
				break;
			case Event.submit_membercard_user_info:
				result = this.OnEvent_Submit_Membercard_User_Info(this.RequestMessage as RequestMessageEvent_Submit_Membercard_User_Info);
				break;
			case Event.ShakearoundUserShake:
				result = this.OnEvent_ShakearoundUserShake(this.RequestMessage as RequestMessageEvent_ShakearoundUserShake);
				break;
			default:
				throw new UnknownRequestMsgTypeException("未知的Event下属请求信息", null);
			}
			return result;
		}
		public virtual IResponseMessageBase OnEvent_EnterRequest(RequestMessageEvent_Enter requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_LocationRequest(RequestMessageEvent_Location requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_UnsubscribeRequest(RequestMessageEvent_Unsubscribe requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_ClickRequest(RequestMessageEvent_Click requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_ScanRequest(RequestMessageEvent_Scan requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_ViewRequest(RequestMessageEvent_View requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_MassSendJobFinishRequest(RequestMessageEvent_MassSendJobFinish requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_TemplateSendJobFinishRequest(RequestMessageEvent_TemplateSendJobFinish requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_PicPhotoOrAlbumRequest(RequestMessageEvent_Pic_Photo_Or_Album requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_ScancodePushRequest(RequestMessageEvent_Scancode_Push requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_ScancodeWaitmsgRequest(RequestMessageEvent_Scancode_Waitmsg requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_LocationSelectRequest(RequestMessageEvent_Location_Select requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_PicWeixinRequest(RequestMessageEvent_Pic_Weixin requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_PicSysphotoRequest(RequestMessageEvent_Pic_Sysphoto requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_Card_Pass_CheckRequest(RequestMessageEvent_Card_Pass_Check requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_Card_Not_Pass_CheckRequest(RequestMessageEvent_Card_Not_Pass_Check requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_User_CardRequest(RequestMessageEvent_User_Card requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_User_Del_CardRequest(RequestMessageEvent_User_Del_Card requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_Kf_Create_SessionRequest(RequestMessageEvent_Kf_Create_Session requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_Kf_Close_SessionRequest(RequestMessageEvent_Kf_Close_Session requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_Kf_Switch_SessionRequest(RequestMessageEvent_Kf_Switch_Session requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_Poi_Check_NotifyRequest(RequestMessageEvent_Poi_Check_Notify requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_WifiConnected(RequestMessageEvent_WifiConnected requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_User_Consume_Card(RequestMessageEvent_User_Consume_Card requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_User_Enter_Session_From_Card(RequestMessageEvent_User_Enter_Session_From_Card requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_User_View_Card(RequestMessageEvent_User_View_Card requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_Merchant_Order(RequestMessageEvent_Merchant_Order requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_Submit_Membercard_User_Info(RequestMessageEvent_Submit_Membercard_User_Info requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
		public virtual IResponseMessageBase OnEvent_ShakearoundUserShake(RequestMessageEvent_ShakearoundUserShake requestMessage)
		{
			return this.DefaultResponseMessage(requestMessage);
		}
	}
}
